/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import exception.InvalidTestScriptPlaybackCommandException;
import exception.InvalidSTAFCommandException;
import exception.BuildNameNotSetException;
import exception.InvalidCommandException;
import exception.InvalidCommandReferenceException;
import exception.InvalidVMHostNameException;
import exception.RFTInstallPathNotFoundException;
import exception.ScriptLogNotFoundException;
import exception.ScriptPlaybackFailureException;
import exception.TestScriptAlreadyExecutedException;
import exception.VMNotSetupException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.Thread.State;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import util.FileSystemWatcher;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface OptionalParameter {

    int value();
}

/**
 *
 * @author pyin
 */
public class Command implements Executable {

    private String cmd;
    private CommandExecutionThread thread;
    private int status;
    private VMMachine machine = null;
//    private String output = "";
//    private int result = -1;
    private TestScriptManager tsManager;
    private CommandResult result;

    public String getCmd() {
        return cmd;
    }

    public boolean isSucceed() {
        return this.result.isSucceed();
    }

    public void setResult(CommandResult result) {
        this.result = result;
    }

    public String getOutput() {
        return this.result.getOutput();
    }

    public void setStatus(int stat) {
        this.status = stat;
    }

    public void setMachine(VMMachine machine) {
        this.machine = machine;
    }

    public VMMachine getMachine() {
        return this.machine;
    }

    //Be careful with the regular expression!!!
    private final String[] patterns = {
        "(ls)\\s+([^\\s]+)\\s+([^\\s]+)+$",
        "(ls)\\s+([^\\s]+)",
        "(qs)\\s+([^\\s]+)",
        "(lgs)\\s+([^\\s]+)\\s+([^\\s]+)\\s+onComplete:([^\\s]+)",
        "(lgs)\\s+([^\\s]+)\\s+onComplete:([^\\s]+)",
        "(echo)\\s+([^\\s]+)$",
        "(go)\\s+([^\\s]+)\\s+$",
        "(up)\\s+([-\\w\\[\\]|]+)$",
        "(up)",
        "(lm)\\s+([-\\w\\[\\]|]+)$",
        "(use)\\s+([-\\w\\[\\]|]+)$",
        "(sm)\\s+([-\\w\\[\\]|]+)$",
        "(qm)\\s+([-\\w\\[\\]|]+)$",
        "(qm)",
        "(machine)",
        "(help)$",
        "(rc)$",
        "(setup)\\s+([-\\w\\[\\]|]+)$",
        "(setup)",
        "(reset)\\s+([-\\w\\[\\]|]+)$",
        "(reset)",
        "(sb)\\s+([-\\w\\[\\]|]+)$",
        "(watch)\\s+([-_\\.\\*\\+?\\w\\[\\]|]+)$",
        "(showme)\\s+([-\\w\\[\\]|]+)$",
        "(an)\\s+([-\\w\\[\\]|]+)$",
        "(qs)\\s+([-\\w\\[\\]|]+)$"
    };

    public Command(String cmd) {
        this.cmd = cmd;
    }

    public Command(String cmd, TestScriptManager tsManager) {
        this.cmd = cmd;
        this.tsManager = tsManager;
    }

    public boolean isValid() {
        for (int i = 0; i < patterns.length; i++) {
            Pattern p = Pattern.compile(patterns[i]);
            Matcher m = p.matcher(this.cmd.toLowerCase());
            if (m.find()) {
                return true;
            }
        }
        return false;
    }

    public boolean isRunOnSameMachine(Command cmd) {
        return this.getMachine().equals(cmd.getMachine());
    }

    public void an(String notification) {
        NotificationManager.addNotification("an " + notification, notification);
//        this.result = 0;
//        this.output = "New notification is created";
        this.setResult(new CommandResult(0, "New notification is created"));
    }

    public void use(String machine) {
        try {
            VMMachine m = VMMachineFactory.getVMMachine(machine);
            ConfigManager.setMachine(machine);
//            this.result = 0;
            this.setResult(new CommandResult(0, "Machine " + machine + " is defined as you default machine"));
        } catch (InvalidVMHostNameException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        }
    }

    public void machine() {
        String m = ConfigManager.getMachine();
        if (m != null) {
            this.setResult(new CommandResult(0, m));
//            this.result = 0;
//            this.output = m;
        } else {
            this.setResult(new CommandResult(1, "Not defined"));
//            this.result = 0;
//            this.output = "Not defined";
        }
    }

    public void rc() {
        if (ConfigManager.reload() && VMMachineFactory.reload()) {
            this.setResult(new CommandResult(0, "All configurations are reloaded."));
        } else {
            this.setResult(new CommandResult(1, "Error in reloading configurations."));
        }
    }

    @OptionalParameter(0)
    public void up(String hostName) {
        try {
            VMMachine machine = VMMachineFactory.getVMMachine(hostName);
            if (machine.createServerSideProjectArchive() && machine.getProjectArchive() && machine.extractProjectArchive()) {
                this.setResult(new CommandResult(0, "Sucessfully update project on machine " + hostName));
            } else {
                this.setResult(new CommandResult(1, "Failed to update project on machine " + hostName));
            }
        } catch (InvalidVMHostNameException ex) {
            Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
            this.setResult(new CommandResult(1, ex.getMessage()));
        }

    }

    public void echo(String msg) {
        this.setResult(new CommandResult(0, msg));
    }

    @OptionalParameter(0)
    public void reset(String m) {
        try {
            VMMachine machine = VMMachineFactory.getVMMachine(m);
            machine.restore(ConfigManager.getBuildName());
            this.setResult(new CommandResult(0, "Machine  " + m + " has been successfully restored."));
        } catch (InvalidVMHostNameException ex) {
            Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (BuildNameNotSetException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }

    }

    public void watch(String expectedPattern) {
        try {
            FileSystemWatcher watcher = new FileSystemWatcher(ConfigManager.getBiuldReleasePath(), expectedPattern, ConfigManager.getNewBuildWatchFrequency(), true);
//            FileSystemWatcher watcher = new FileSystemWatcher(ConfigManager.getBiuldReleasePath(), expectedPattern, 600, true);
            watcher.start();
            this.setResult(new CommandResult(0, watcher.getDetected()));
        } catch (IOException ex) {
            this.setResult(new CommandResult(1, "The path specified does not exist"));
        }
    }

    private boolean ifDirContainsFile(String dir, String fileName) {
        File currentDir = new File(dir);
        if (!currentDir.exists()) {
            return false;
        }
        String[] allFiles = currentDir.list();
        for (int i = 0; i < allFiles.length; i++) {
            if (allFiles[i].toLowerCase().endsWith(fileName.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    //It's a very bad idea to invoke another command from within command.
    public void sb(String buildName) {
        File root = new File(ConfigManager.getInstallerPath());
        if (ifDirContainsFile(ConfigManager.getInstallerPath(), buildName)) {
            ConfigManager.setBuildName(buildName);
            this.setResult(new CommandResult(0, "BuildName already set to " + buildName));
        } else {
            File releaseDir = new File(ConfigManager.getBiuldReleasePath());
            String file;
            if (ifDirContainsFile(ConfigManager.getBiuldReleasePath(), buildName)) {
                file = ConfigManager.getBiuldReleasePath() + "\\" + buildName;
            } else {
                file = NotificationManager.getNotification("watch " + buildName);
            }
            if (file != null) {
                try {
                    File f = new File(file);
                    if (f.isFile()) {
                        copyFile(f, new File(ConfigManager.getInstallerPath() + "\\" + f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\"), f.getAbsolutePath().length())));
                    }
                    if (f.isDirectory()) {
                        copyDir(f, new File(ConfigManager.getInstallerPath() + "\\" + buildName));
                    }
                    ConfigManager.setBuildName(buildName);
                    this.setResult(new CommandResult(0, "New build is copied to the installer path and build name is set to " + buildName));
                } catch (IOException ex) {
                    this.setResult(new CommandResult(1, "IOException thrown when copying file" + file));
                    NotificationManager.addNotification("sb " + buildName, "IOException thrown when copying file" + file);
                }
            } else {
                this.setResult(new CommandResult(1, "prerequiste not met"));
            }
//            else {
//                if (!CommandRunner.isCommandRunning("watch " + buildName) && !CommandRunner.isCommandQueued("watch "+buildName)) {
//                    Command command = new Command("watch " + buildName);
//                    CommandRunner.addCommand(command);
//                    sb(buildName);
//                }
//            }
        }
    }

    private void copyFile(File s, File t) throws IOException {

        FileChannel in = (new FileInputStream(s)).getChannel();
        FileChannel out = (new FileOutputStream(t)).getChannel();
        in.transferTo(0, s.length(), out);
        in.close();
        out.close();
    }

    private void copyDir(File sourceLocation, File targetLocation) throws IOException {
        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists()) {
                targetLocation.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < children.length; i++) {
                copyDir(new File(sourceLocation, children[i]),
                        new File(targetLocation, children[i]));
            }
        } else {

            InputStream in = new FileInputStream(sourceLocation);
            OutputStream out = new FileOutputStream(targetLocation);

            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }
    }

    @OptionalParameter(0)
    public void setup(String hostName) {
        try {
            this.machine = VMMachineFactory.getVMMachine(hostName);
            if (machine.hasCurrentBuildSnapshot()) {
                this.setResult(new CommandResult(0, this.machine.getName() + " has already been setup"));
            } else {
                int result = machine.setupEnv(ConfigManager.getBuildName());
                switch (result) {
                    case 1:
                        this.setResult(new CommandResult(1, "Failed to revert to clean snapshot"));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 2:
                        this.setResult(new CommandResult(1, "Failed to start machine " + hostName));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 3:
                        this.setResult(new CommandResult(1, "Failed to create RFT project zip file"));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 4:
                        this.setResult(new CommandResult(1, "Failed to copy RFT project to target machine " + hostName));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 5:
                        this.setResult(new CommandResult(1, "Failed to extract RFT project"));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 6:
                        this.setResult(new CommandResult(1, "Failed to copy installer archive"));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 7:
                        this.setResult(new CommandResult(1, "Failed to copy extract installer archive"));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 8:
                        this.setResult(new CommandResult(1, "Failed to shut down machine " + hostName));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 9:
                        this.setResult(new CommandResult(1, "Failed to create snapshot " + ConfigManager.getBuildName()));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 10:
                        this.setResult(new CommandResult(1, "Failed to start machine " + hostName));
//                        NotificationManager.addNotification(this.cmd, this.output);
                        break;
                    case 0:
                        this.setResult(new CommandResult(0, "Done"));
                        break;
                }
            }
        } catch (InvalidVMHostNameException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        } catch (BuildNameNotSetException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }
    }

    public void qs(String pattern) {
        try {
            List scripts = TestScriptManager.getScriptNames(pattern);
            Iterator it = scripts.iterator();
//            this.output = "";
//            while (it.hasNext()) {
//                this.output = this.output + it.next().toString();
//                this.output = this.output + "<br>";
//            }
//            this.result = 0;
            this.setResult(new CommandResult(0, scripts.size() + " scripts", scripts));
        } catch (FileNotFoundException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        }

    }

//    public void qsa() {
//        try {
//            String text = "";
//            List scripts = TestScriptManager.getAllScriptNames();
//            Iterator it = scripts.iterator();
//            while (it.hasNext()) {
//                String line = ((String) it.next()).replace(".java", "");
//                text = text + line + "<br>";
//            }
//            this.output = text;
//            this.result = 0;
//        } catch (FileNotFoundException ex) {
//            this.output = "Script folder not found";
//            this.result = 1;
//        }
//    }
    private String[] getPatterns() {
        return this.patterns;
    }

    @OptionalParameter(1)
    public void lgs(String groupPattern, String hostname, String linkCmd) {
        Pattern pattern = Pattern.compile(groupPattern);
        try {
//            List allNames = TestScriptManager.getAllScriptNames();
//            Iterator it = allNames.iterator();
//            List<TestScript> allScripts = new ArrayList<TestScript>();
//            while (it.hasNext()) {
//                TestScript script = new TestScript(it.next().toString(), hostname);
//                if (groupPattern.equalsIgnoreCase("all") || groupPattern.equals("*")) {
//                    allScripts.add(script);
//                } else {
//                    Matcher matcher = pattern.matcher(script.getScriptName());
//                    if (matcher.find()) {
//                        allScripts.add(script);
//                    }
//                }
//            }
            List scriptNames = TestScriptManager.getScriptNames(groupPattern);
            List allScripts = new ArrayList();
            Iterator namesIterator = scriptNames.iterator();
            while (namesIterator.hasNext()) {
                String name = (String) namesIterator.next();
                TestScript script = new TestScript(name, hostname);
                allScripts.add(script);
            }

            String cmd = linkCmd + " " + hostname;
            TestScriptGroup group = new TestScriptGroup(allScripts, cmd);
            this.setResult(new CommandResult(0, group.getScriptCount() + " scripts have been executed in batch execution."));
            group.run();
        } catch (InvalidVMHostNameException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (FileNotFoundException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (BuildNameNotSetException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }

    }

    @OptionalParameter(1)
    public void ls(String scriptName, String hostname) {
//        System.out.println("ls " + scriptName);
        try {
//            String tsName = scriptName+"["+ConfigManager.getBuildName()+"]"+hostname;
//            String tsName = scriptName+"["+hostname+"]"+ConfigManager.getBuildName();
//            TestScript script = TSManager.getScript(tsName);
            TestScript script = new TestScript(scriptName, hostname);
            script.run();
            String result = script.getResult().isPassed() ? "passed" : "failed";
            this.setResult(new CommandResult(0, "Script [" + script.getScriptName() + "] " + result));
            NotificationManager.addNotification("ls", this.getResult().getOutput());
        } catch (ScriptLogNotFoundException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (ScriptPlaybackFailureException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (InvalidTestScriptPlaybackCommandException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (VMNotSetupException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (BuildNameNotSetException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (TestScriptAlreadyExecutedException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (InvalidSTAFCommandException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (RFTInstallPathNotFoundException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (InvalidVMHostNameException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        }
    }

//    public void help() {
//        FileReader fr = null;
//        try {
//            fr = new FileReader(ConfigManager.getUsageFilePath());
//            BufferedReader br = new BufferedReader(fr);
//            String line;
//            while ((line = br.readLine()) != null) {
//                this.output = this.output + line + "<br>";
//            }
//            System.out.println(this.output);
//            this.result = 0;
//        } catch (IOException ex) {
//            this.result = 1;
//            this.output = "Cannot find file usage.txt";
//        } finally {
//            try {
//                fr.close();
//            } catch (IOException ex) {
//                Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
//            }
//        }
//    }
    public void lm(String machineName) {
        try {
            VMMachine machine = VMMachineFactory.getVMMachine(machineName);
            this.machine = machine;
            if (machine == null) {
                this.setResult(new CommandResult(1, "The machine is not on list, please try another one"));
            } else {
                if (machine.start()) {
                    this.setResult(new CommandResult(0, machineName + " started."));
                } else {
                    this.setResult(new CommandResult(1, "Failed to start " + machineName));
                }
            }
        } catch (InvalidVMHostNameException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }
    }

    public void sm(String machineName) {
        try {
            VMMachine machine = VMMachineFactory.getVMMachine(machineName);
            this.machine = machine;
            if (machine == null) {
                this.setResult(new CommandResult(1, "The machine is not on list, please try another one"));
            } else {
                if (this.machine.start()) {
                    this.setResult(new CommandResult(0, "Start machine successfully."));
                } else {
                    this.setResult(new CommandResult(1, "Start machine failed"));
                }
            }
        } catch (InvalidVMHostNameException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }
    }

    @OptionalParameter(0)
    public void qm(String machineName) {
        try {
            if (machineName.trim().equalsIgnoreCase("all")) {
                List machines = VMMachineFactory.getVMMachines();
                Iterator it = machines.iterator();
                String result = "";
                while (it.hasNext()) {
                    VMMachine machine = (VMMachine) it.next();
                    result = result + machine.getName() + "<br>";
                }
                this.setResult(new CommandResult(0, result));
            }
            VMMachine machine = VMMachineFactory.getVMMachine(machineName);
            String status = machine.isHostingMachineReady() ? "running" : "stopped";
            String[] snapshots = machine.getSnapshots();
            String ss = "";
            if (snapshots != null) {
                for (int i = 0; i < snapshots.length; i++) {
                    ss = ss + snapshots[i] + "<br>";
                }
            }
            String result = "hostname:\t" + machine.getName() + "<br>" + "host on:\t" + machine.getVmHost() + status + "<br>" + "OS:\t" + machine.getOs() + " <br>snapshots:" + ss;
            this.setResult(new CommandResult(0, result));
        } catch (InvalidVMHostNameException e) {
            this.setResult(new CommandResult(1, e.getMessage()));
        }

    }

    public void run() throws InvalidCommandException, InvalidCommandReferenceException {
        boolean foundMethod = false;
        for (int i = 0; i < patterns.length; i++) {
            Pattern p = Pattern.compile(patterns[i]);
            Matcher m = p.matcher(cmd);
//            Matcher m = p.matcher(cmd.toLowerCase());
            if (m.find()) {
                String method = m.group(1);
                String[] args = new String[m.groupCount() - 1];
                for (int j = 0; j < args.length; j++) {
                    args[j] = m.group(j + 2);
                }
                Method[] methods = this.getClass().getMethods();
                for (int j = 0; j < methods.length; j++) {
                    String methodString = methods[j].getName();
                    if (methodString.equalsIgnoreCase(method)) {
                        foundMethod = true;
                        thread = new CommandExecutionThread(this, methods[j], args);
                        thread.start();
                        if (this.status == -2) {
                            throw new InvalidCommandException();
                        }
                        while (thread.getState() != State.TERMINATED) {
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }

            }
        }
        if (!foundMethod) {
            throw new InvalidCommandException();
        }
    }

    public boolean finished() {
        return (this.result.getRc() >= 0);
//        return this.thread.getState()==State.TERMINATED;
    }

    /**
     * @return the result
     */
    public CommandResult getResult() {
        return result;
    }

    class CommandExecutionThread extends Thread {

        Command parent;
        Object[] args;
        Method method;
        String result;

        public CommandExecutionThread(Command command, Method method, Object[] parameters) throws InvalidCommandReferenceException {
            this.parent = command;
            this.args = parameters;
            this.method = method;
            handleOptionalParameter();
            handleVariableParamenter();

        }

        private void handleVariableParamenter() throws InvalidCommandReferenceException {
            try {
                for (int i = 0; i < this.args.length; i++) {
                    Pattern dataPattern = Pattern.compile("\\$(\\d+)d(\\d+)");
                    Matcher matcher = dataPattern.matcher((String) args[i]);
                    if (matcher.matches()) {
                        int commandIndex = new Integer(matcher.group(1)).intValue() - 1;
                        int dataIndex = new Integer(matcher.group(2)).intValue() - 1;
                        String commandResult = CommandResultManager.getCommand(commandIndex).getResult().getData(dataIndex);
                        this.args[i] = commandResult;
//                    ((String)this.args[i]).replace(matcher.group(0), commandResult);
                    }
                    Pattern outputPattern = Pattern.compile("\\$(\\d+)");
                    matcher = outputPattern.matcher((String) args[i]);
                    if (matcher.matches()) {
                        int commandIndex = new Integer(matcher.group(1)).intValue() - 1;
                        String commandOutput = CommandResultManager.getCommand(commandIndex).getResult().getOutput();
                        this.args[i] = commandOutput;
                    }
                }
            } catch (NullPointerException e) {
                throw new InvalidCommandReferenceException();
            }
        }

        @Override
        public void run() {
            try {
                method.invoke(this.parent, this.args);
//                result = (String) method.invoke(this.parent, this.args);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                if (ex.getCause() instanceof java.lang.StringIndexOutOfBoundsException) {
                    this.parent.setStatus(-2);
                }
                Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

        private String getResult() {
            return result;
        }

        private void handleOptionalParameter() {
            //Add ConfigManager.getMachine to args if optional parameter not exist.
            int definition = this.method.getParameterTypes().length;
            if (definition == this.args.length + 1) {
                int index = this.method.getAnnotation(OptionalParameter.class).value();
                Object[] para = new Object[definition];
                if (definition == 1) {
                    para[0] = ConfigManager.getMachine();
                } else {
                    for (int i = 0; i < this.args.length; i++) {
                        if (i < index) {
                            para[i] = this.args[i];
                        } else {
                            para[i + 1] = this.args[i];
                        }
                    }
                    para[index] = ConfigManager.getMachine();
                }
                this.args = para;
            }
        }
    }

    public static void main(String[] args) {
        try {
            ConfigManager.setBuildName("sup15drop_m3b_drop2");
            Command cmd = new Command("qs Script.install_.*");
//            Command cmd = new Command("lgs Script\\d win03uepinstall onTerminate:none");
            cmd.run();
            System.out.println(cmd.getResult().getData(1));
//            System.out.println(cmd.getOutput());
//            cmd = new Command("fuck");
//            System.out.println(cmd.getOutput());
            System.out.println(cmd.getOutput());
            for (int i = 0; i < cmd.getResult().getData().size(); i++) {
                System.out.println(cmd.getResult().getData(i));
            }
        } catch (InvalidCommandReferenceException ex) {
            Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidCommandException ex) {
            System.out.println("invalid arguments");
        }
    }
}
